#ifndef __COMPONENT_FLY_AWAY_BEHAVIOR_H__
#define __COMPONENT_FLY_AWAY_BEHAVIOR_H__

#include "ComponentBehavior.hpp"
#include "Engine/MathUtils.hpp"
#include "Engine/Vector2.hpp"

#include "EasyMachine.hpp"
#include "INoiseListener.hpp"

using namespace PocketSurvival::Engine;

namespace PocketSurvival
{
    struct ComponentCreature;
    struct ComponentBody;
    struct ComponentPathfinding;

    class SubsystemNoise;

    struct ComponentFlyAwayBehavior : public ComponentBehavior, public INoiseListener
    {
    protected:
        enum class MachineState
        {
            LookingForDanger,       // 寻找危险
            DangerDetected,         // 检测到危险
            RunningAway             // 逃跑
        };

        class StateMachine : public EasyMachine<MachineState>
        {
        protected:
            ComponentFlyAwayBehavior * m_flyAway;
        public:
            StateMachine(ComponentFlyAwayBehavior *flyAway);

            virtual void enter() override;
            virtual void update(float dt) override;
            virtual void leave() override;
        };

    protected:
        float m_angle;
        double m_nextUpdateTime;
        float m_importanceLevel = 0.0f;
        StateMachine *m_stateMachine;
        std::vector<ComponentBody*> m_componentBodyVec;

    public:
        ComponentCreature *componentCreature;
        ComponentPathfinding *componentPathfinding;

        SubsystemNoise *subsystemNoise;



        ComponentFlyAwayBehavior() = default;
        ~ComponentFlyAwayBehavior();

        virtual void setActive(bool active) override;
        virtual void hearNoise(ComponentBody *sourceBody, const Vector3& sourcePosition, float loudness) override;
        virtual float getImportanceLevel() override;

        bool scanForDanger();
        Vector3 findSafePlace();
        float scoreSafePlace(const Vector3 &currentPosition, const Vector3 &safePosition, std::shared_ptr<Vector3> lookDirection);
        bool isPredator(ComponentCreature *creature);

        virtual void update(float dt) override;
        virtual void load(const nlohmann::json &jsonData) override;
        virtual const std::string &getName() const override;
        static const std::string &GetName();

    protected:
        void collidedWithBodyEvent(ComponentBody *body);
    };
}

#endif
